﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;

namespace Design
{
    public enum ElementType
    {
        ELE_LABEL = 0,
        ELE_TEXTBOX = 1,
        ELE_COMBBOX = 2,
        ELE_TABLE,
        ELE_UNKNOW
    }

    public enum ErrorCode
    {
        ERR_OK = 0,

        ELEMENT_TYPE_UNKNOW = 100,
        ELEMENT_EXIST,
        XML_NODE_NULL = 200,
        XML_DOC_NULL,
        XML_NODE_ID_NULL,
        ERR_UNKNOW
    }

    class CXmlCtrl
    {
        XmlDocument m_xmlDoc;
        XmlNode     xmlnode;
        static CXmlCtrl insXmlCtrl = null;

        private CXmlCtrl()
        {
            m_xmlDoc = new XmlDocument();
        }

        public static CXmlCtrl GetInstance()
        {
            if (null == insXmlCtrl)
            {
                insXmlCtrl = new CXmlCtrl();
            }

            return insXmlCtrl;
        }

        public ErrorCode ProcessConfigXml()
        {
            ErrorCode  errCode;
            
            errCode = IsExistConfigFile();
            if (ErrorCode.ERR_OK != errCode)
            {
                return errCode;
            }

            //string sId = null;
            //GetEleCtrlId(ElementType.ELE_COMBBOX, ref sId);
            //SetEleCtrlId(ElementType.ELE_COMBBOX, sId);

            return ErrorCode.ERR_OK;
        }

        private ErrorCode IsExistConfigFile()
        {
            ErrorCode errCode = ErrorCode.ERR_OK;

            if (false == File.Exists("DataConfig.xml"))
            {
                errCode = CreateConfigXml();
            }

            return errCode;
        }

        private ErrorCode CreateConfigXml()
        {
            XmlElement xmlelem_root;

            //加入XML的声明段落
            xmlnode = m_xmlDoc.CreateNode(XmlNodeType.XmlDeclaration, "", "");
            m_xmlDoc.AppendChild(xmlnode);
            //加入一个根元素
            xmlelem_root = m_xmlDoc.CreateElement("", "Config", "");
            //xmltext = m_xmlDoc.CreateTextNode("Root Text");
            //xmlelem.AppendChild(xmltext);
            m_xmlDoc.AppendChild(xmlelem_root);

            //加入另外一个元素
            CreateElementType(xmlelem_root);

            //保存创建好的XML文档
            try
            {
                m_xmlDoc.Save("DataConfig.xml");
            }
            catch (Exception e)
            {
                //显示错误信息
                Console.WriteLine(e.Message);
            }

            return ErrorCode.ERR_OK;
        }

        private void CreateElementType(XmlElement xmlRoot)
        {
            XmlElement xmlelem_parent, xmlelem1, xmlelem2;

            xmlelem_parent = m_xmlDoc.CreateElement("Element_Type");
            xmlelem_parent = m_xmlDoc.CreateElement("", "Element_Type", "");
            xmlRoot.AppendChild(xmlelem_parent);

            xmlelem1 = AddChildElement(xmlelem_parent, "TextBox");
            xmlelem1.SetAttribute("Total", "0");
            xmlelem2 = AddChildElement(xmlelem1, "ID");
            xmlelem_parent.AppendChild(xmlelem1);

            xmlelem1 = AddChildElement(xmlelem_parent, "Label");
            xmlelem1.SetAttribute("Total", "0");
            xmlelem2 = AddChildElement(xmlelem1, "ID");
            xmlelem_parent.AppendChild(xmlelem1);

            xmlelem1 = AddChildElement(xmlelem_parent, "CombBox");
            xmlelem1.SetAttribute("Total", "0");
            xmlelem2 = AddChildElement(xmlelem1, "ID");
            xmlelem_parent.AppendChild(xmlelem1);

            xmlelem1 = AddChildElement(xmlelem_parent, "Table");
            xmlelem1.SetAttribute("Total", "0");
            xmlelem2 = AddChildElement(xmlelem1, "ID");
            xmlelem_parent.AppendChild(xmlelem1);
        }

        private XmlElement AddChildElement(XmlElement xmlRoot, string sElement)
        {
            XmlElement xmlelem;

            xmlelem = m_xmlDoc.CreateElement(sElement);
            xmlelem = m_xmlDoc.CreateElement("", sElement, "");
            xmlRoot.AppendChild(xmlelem);

            return xmlelem;
        }

        private ErrorCode GetCtrlTotal(XmlDocument xmlDoc, string sNameCtrl, ref string sCtrlId)
        {
            XmlNode xmlnode = xmlDoc.GetElementsByTagName(sNameCtrl).Item(0);
            XmlElement xmlElement = (XmlElement)xmlnode;

            if (null == xmlElement)
            {
                return ErrorCode.XML_NODE_NULL;
            }

            string sTotal = "";
            int iTotal = 0;

            sTotal = xmlElement.GetAttribute("Total");
            iTotal = int.Parse(sTotal);
            iTotal++;

            sCtrlId = string.Format("{0:D4}", iTotal);

            return ErrorCode.ERR_OK;
        }

        public ErrorCode GetEleCtrlId(ElementType eleType, ref string sId)
        {
            ErrorCode errCode = ErrorCode.ERR_OK;
            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.Load("DataConfig.xml");

            if (null == xmlDoc)
            {
                return ErrorCode.XML_DOC_NULL;
            }

            switch (eleType)
            {
                case ElementType.ELE_TEXTBOX:
                {
                    errCode = GetCtrlTotal(xmlDoc, "TextBox", ref sId);

                    break;
                }
                case ElementType.ELE_COMBBOX:
                {
                    errCode = GetCtrlTotal(xmlDoc, "CombBox", ref sId);

                    break;
                }
                case ElementType.ELE_LABEL:
                {
                    errCode = GetCtrlTotal(xmlDoc, "Label", ref sId);

                    break;
                }
                default:
                {
                    return ErrorCode.ELEMENT_TYPE_UNKNOW;
                }
            }

            return errCode;
        }

        private ErrorCode SetCtrlId(XmlDocument xmlDoc, string sNameCtrl, string sCtrlId)
        {
            ErrorCode errCode = ErrorCode.ERR_OK;

            XmlNode xmlnode = xmlDoc.GetElementsByTagName(sNameCtrl).Item(0);
            XmlElement xmlElement = (XmlElement)xmlnode;

            if (null == xmlElement)
            {
                return ErrorCode.XML_NODE_NULL;
            }

            XmlNode xmlNodeId = xmlElement.GetElementsByTagName("ID").Item(0);
            XmlElement xmlElementId = (XmlElement)xmlnode;

            if (null == xmlElementId)
            {
                return ErrorCode.XML_NODE_NULL;
            }

            string[] argStrId;

            argStrId = xmlElementId.InnerText.Split(',');

            for (int i = 0; i < argStrId.Length; i++)
            {
                if (sCtrlId.Equals(argStrId[i]))
                {
                    return ErrorCode.ELEMENT_EXIST;
                }
            }

            if (0 == argStrId.Length)
            {
                xmlElementId.InnerText = string.Format("{1},", sCtrlId);
            }
            else
            {
                xmlElementId.InnerText = string.Format("{0}{1},", 
                    xmlElementId.InnerText, sCtrlId);
            }

            string sTotal = xmlElement.GetAttribute("Total");
            int iTotal = int.Parse(sTotal);
            iTotal++;

            sCtrlId = string.Format("{0:D4}", iTotal);
            xmlElement.SetAttribute("Total", sCtrlId);

            return errCode;
        }

        //sCtrlId must like TEXTBOX_0001, TEXTBOX_0002
        public ErrorCode SetEleCtrlId(ElementType eleType, string sCtrlId)
        {
            ErrorCode errCode = ErrorCode.ERR_OK;
            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.Load("DataConfig.xml");

             if (null == xmlDoc)
            {
                return ErrorCode.XML_DOC_NULL;
            }

            switch (eleType)
            {
                case ElementType.ELE_TEXTBOX:
                {
                    errCode = SetCtrlId(xmlDoc, "TextBox", sCtrlId);

                    break;
                }
                case ElementType.ELE_COMBBOX:
                {
                    errCode = SetCtrlId(xmlDoc, "CombBox", sCtrlId);

                    break;
                }
                case ElementType.ELE_LABEL:
                {
                    errCode = SetCtrlId(xmlDoc, "Label", sCtrlId);

                    break;
                }
                default:
                {
                    errCode = ErrorCode.ELEMENT_TYPE_UNKNOW;
                    break;
                }
            }

            if (ErrorCode.ERR_OK == errCode)
            {
                xmlDoc.Save("DataConfig.xml");
            }

            return errCode;
        }
    }
}
